package cn.shopping.core.controller;

import cn.shopping.common.controller.BaseController;
import cn.shopping.common.exception.CommonErrorCode;
import cn.shopping.common.exception.CommonException;
import cn.shopping.common.util.CommonUtils;
import cn.shopping.common.vo.ResponseVO;
import cn.shopping.core.bo.UploadInfoWithInputStreamBO;
import cn.shopping.core.dbo.UploadInfoDO;
import cn.shopping.core.dto.UploadBase64DTO;
import cn.shopping.core.service.UploadService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.List;

/**
 * 描述:
 *
 * @author Zhanggq
 * @date 2019/4/8 14:21
 */
@RestController
@RequestMapping(value = "/webapi/uploadFile/", method = RequestMethod.POST)
@Api(description = "附件上传删除接口")
public class UploadInfoController extends BaseController {

    private static final Logger logger = LoggerFactory.getLogger(GoodsController.class);

    @Autowired
    private UploadService uploadService;

    /**
     * 文件上传
     *
     * @param file
     * @param userId
     * @param detail
     * @return
     * @throws Exception
     */
    @ApiOperation("文件上传")
    @RequestMapping(value = "upload", method = RequestMethod.POST)
    public ResponseVO<UploadInfoDO> upload(@RequestParam("file") MultipartFile file,
                                           @RequestParam(value = "userId", required = false) Long userId,
                                           @RequestParam(value = "detail", required = false) String detail) throws Exception {
        if (file == null) {
            throw CommonException.exception(CommonErrorCode.PARAM_ERROR_CODE, "传入文件有误。");
        }
        UploadInfoDO uploadInfoDO = uploadService.uploadFile(file, userId, detail);
        return CommonUtils.okResponseVO(uploadInfoDO);
    }


    @ApiOperation("文件原图上传")
    @RequestMapping(value = "uploadOriginalFile", method = RequestMethod.POST)
    public ResponseVO<UploadInfoDO> uploadOriginalFile(@RequestParam("file") MultipartFile file,
                                                       @RequestParam(value = "userId", required = false) Long userId,
                                                       @RequestParam(value = "detail", required = false) String detail) throws Exception {
        if (file == null) {
            throw CommonException.exception(CommonErrorCode.PARAM_ERROR_CODE, "传入文件有误。");
        }
        UploadInfoDO uploadInfoDO = uploadService.uploadOriginalFile(file, userId, detail);
        return CommonUtils.okResponseVO(uploadInfoDO);
    }

    /**
     * 多文件上传
     *
     * @param files
     * @param userId
     * @param detail
     * @return
     * @throws Exception
     */
    @ApiOperation("多文件上传")
    @RequestMapping(value = "uploads", method = RequestMethod.POST)
    public ResponseVO<List<UploadInfoDO>> uploads(@RequestParam("files") MultipartFile[] files,
                                                  @RequestParam(value = "userId", required = false) Long userId,
                                                  @RequestParam(value = "detail", required = false) String detail) throws Exception {
        if (files == null || files.length == 0) {
            throw CommonException.exception(CommonErrorCode.PARAM_ERROR_CODE, "传入文件有误。");
        }
        List<UploadInfoDO> uploadInfoDO = uploadService.uploadFiles(files, userId, detail);
        return CommonUtils.okResponseVO(uploadInfoDO);
    }

    /**
     * 上传图片以base64上传
     *
     * @param dto
     * @return
     */
    @ApiOperation("上传图片以base64上传，支持多张上传")
    @RequestMapping(value = "uploadBase64", method = RequestMethod.POST)
    public ResponseVO<List<UploadInfoDO>> uploadBase64(@RequestBody UploadBase64DTO dto) {
        List<UploadInfoDO> uploadInfoDOList = uploadService.uploadBase64(dto);
        return CommonUtils.okResponseVO(uploadInfoDOList);
    }


    /**
     * 文件下载
     *
     * @param request
     * @param response
     * @param id
     */
    @ApiOperation("文件下载")
    @RequestMapping(value = "download", method = RequestMethod.GET)
    public void download(HttpServletRequest request, HttpServletResponse response, @RequestParam("id") Long id) {
        //设置下载头，以及下载名称等等信息
        UploadInfoWithInputStreamBO uploadInfoWithInputStreamBO = uploadService.getUploadInfoWithInputStream(id);
        InputStream inputStream = uploadInfoWithInputStreamBO.getInputStream();
        try {
            String fileName = uploadInfoWithInputStreamBO.getUploadInfo().getOriginalFileName() + "." + uploadInfoWithInputStreamBO.getUploadInfo().getFileSuffix();
            String newFileName = new String(fileName.getBytes("gb2312"), "iso8859-1");
            response.setHeader("content-disposition", "attachment;filename=" + newFileName);
            response.addHeader("Content-Length", "" + uploadInfoWithInputStreamBO.getUploadInfo().getFileSize());
            response.setContentType("application/octet-stream");
            // response.setCharacterEncoding("utf-8");
            IOUtils.copy(inputStream, response.getOutputStream());
            inputStream.close();
            //response.reset();
        } catch (Exception e) {
            throw CommonException.exception("下载文件失败");
        } finally {
            IOUtils.closeQuietly(inputStream);
        }
    }

    /**
     * 文件下载
     *
     * @param request
     * @param response
     * @param id
     */
    @ApiOperation("根据id获取mp3文件，源文件格式为amr")
    @RequestMapping(value = "downloadMp3FromAmrById", method = RequestMethod.GET)
    public void downloadMp3FromAmrById(HttpServletRequest request, HttpServletResponse response, @RequestParam("id") Long id) {
        //设置下载头，以及下载名称等等信息
        UploadInfoWithInputStreamBO uploadInfoWithInputStreamBO = uploadService.getUploadInfoForMp3WithInputStream(id);
        InputStream inputStream = uploadInfoWithInputStreamBO.getInputStream();
        try {
            String fileName = uploadInfoWithInputStreamBO.getUploadInfo().getOriginalFileName() + "." + "mp3";
            String newFileName = new String(fileName.getBytes("gb2312"), "iso8859-1");
            response.setHeader("content-disposition", "attachment;filename=" + newFileName);
            response.setContentType("application/octet-stream");
            IOUtils.copy(inputStream, response.getOutputStream());
            inputStream.close();
        } catch (Exception e) {
            throw CommonException.exception("下载文件失败");
        } finally {
            IOUtils.closeQuietly(inputStream);
        }
    }


    /**
     * 图片显示.输出图片流
     *
     * @param request
     * @param response
     * @param id
     */
    @ApiOperation("图片显示.输出图片流")
    @RequestMapping(value = "picture", method = RequestMethod.GET)
    public void picture(HttpServletRequest request, HttpServletResponse response, @RequestParam("id") Long id, Integer pixel) {
        UploadInfoWithInputStreamBO uploadInfoWithInputStreamBO = uploadService.getUploadInfoWithInputStream(id, pixel);
        UploadInfoDO uploadInfoDO = uploadInfoWithInputStreamBO.getUploadInfo();
        InputStream inputStream = uploadInfoWithInputStreamBO.getInputStream();
        try {
            int i = inputStream.available(); //得到文件大小
            byte data[] = new byte[i];
            inputStream.read(data); //读数据
            inputStream.close();
            response.setContentType("image/png"); //设置返回的文件类型
            OutputStream toClient = response.getOutputStream(); //得到向客户端输出二进制数据的对象
            toClient.write(data); //输出数据
            toClient.close();
        } catch (Exception e) {
            PrintWriter toClient = null; //得到向客户端输出文本的对象
            try {
                toClient = response.getWriter();
            } catch (IOException e1) {
                throw CommonException.exception("打开文件失败！");
            }
            response.setContentType("text/html;charset=UTF-8");
            toClient.write("无法打开图片!");
            toClient.close();
        }

    }

    /**
     * 返回图片的base64编码的字符串
     *
     * @param request
     * @param response
     * @param id
     */
    @ApiOperation("返回图片的base64编码的字符串")
    @RequestMapping(value = "pictureAsBase64", method = RequestMethod.GET)
    public ResponseVO<String> pictureAsBase64(HttpServletRequest request, HttpServletResponse response, @RequestParam("id") Long id) {
        String pictureAsBase64 = uploadService.pictureAsBase64(id);
        return CommonUtils.okResponseVO(pictureAsBase64);
    }

}
